#include "FPCH.h"

#include "FGlyphPage.h"

#include "FGlyph.h"
#include "FFactory.h"

namespace Font
{

	GlyphPage::GlyphPage(Library* a_Library, GlyphMap* a_Owner)
	{
		m_Library = a_Library;

		m_Owner = a_Owner;

		m_CursorX = 0;
		m_CursorY = 0;
		
		m_Texture = NULL;
		m_GlyphPrevious = NULL;

		SetDistanceNewLine(0);
	}
	
	GlyphPage::~GlyphPage()
	{
		if (m_DataOwned)
		{
			delete [] m_Data;
		}
	}

	void GlyphPage::SetDimensions(unsigned int a_Width, unsigned int a_Height)
	{
		m_Width = a_Width;
		m_Height = a_Height;
		m_Pitch = m_Width * 4;
		
		m_Data = new GLubyte[m_Width * m_Height * 4];
		unsigned int* dst = (unsigned int*)m_Data;
		for (unsigned int i = 0; i < m_Width * m_Height; i++)
		{
			*dst++ = tb::PixelMake(0, 0, 0, 0);
		}

		m_DataOwned = true;
	}

	void GlyphPage::WriteGlyphs(const std::vector<GlyphEntry*>& a_Glyphs)
	{
		for (size_t i = 0; i < a_Glyphs.size(); i++)
		{
			if (a_Glyphs[i]->bitmap)
			{
				_WriteGlyph(a_Glyphs[i]);
			}
		}

		m_Texture = m_Owner->GetFont()->GetFamily()->GetLibrary()->GetFactory()->CreateTexture(m_Width, m_Height, m_Data);
		//Compile();
	}

	bool GlyphPage::GetKerning()
	{
		return m_Kerning;
	}

	void GlyphPage::SetKerning(bool a_State)
	{
		m_Kerning = a_State;
	}
	
	int GlyphPage::GetDistanceNewLine()
	{
		return m_DistanceNewLine;
	}

	void GlyphPage::SetDistanceNewLine(int a_Amount)
	{
		m_DistanceNewLine = a_Amount;
	}

	Texture* GlyphPage::GetTexture()
	{
		return m_Texture;
	}

	unsigned int GlyphPage::GetWidth()
	{
		return m_Width;
	}

	unsigned int GlyphPage::GetHeight()
	{
		return m_Height;
	}

	void GlyphPage::_WriteGlyph(GlyphEntry* a_Glyph)
	{
		tb::Pos2 cursor = a_Glyph->cursor;
		const tb::Pos2& dim = a_Glyph->glyph->GetBitmapDimensions();

		GLubyte* dst = m_Data + (cursor.y * m_Pitch) + (cursor.x * 4);
		unsigned int dst_pitch = m_Pitch;
		GLubyte* src = (GLubyte*)a_Glyph->glyph->GetBitmapData();
		unsigned int src_pitch = dim.x;

		tb::Pixel src_color = tb::PixelMake(255, 255, 255);

		for (int y = 0; y < dim.y; y++)
		{
			if (cursor.y >= 0) 
			{
				if (m_DataOwned)
				{
					GLubyte* dst_line = dst;

					for (int x = 0; x < dim.x; x++)
					{
						dst_line[3] = src[x];
						dst_line[2] = 0xFF;
						dst_line[1] = 0xFF;
						dst_line[0] = 0xFF;

						dst_line += 4;
					}
				}
				else
				{
					tb::Pixel* dst_pixel = (tb::Pixel*)dst;

					for (int x = 0; x < dim.x; x++)
					{
						*dst_pixel = tb::PixelBlend(*dst_pixel, src_color, src[x]);

						dst_pixel++;
					}
				}
			}

			cursor.y++;
			dst += dst_pitch;
			src += src_pitch;
		}
	}

	void GlyphPage::Compile()
	{
		/*glGenTextures(1, &m_Handle);
		glBindTexture(GL_TEXTURE_2D, m_Handle);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexImage2D(
			GL_TEXTURE_2D, 0, GL_RGBA, 
			m_Width, m_Height, 
			0, 
			GL_RGBA, GL_UNSIGNED_BYTE, m_Data
		);
		glBindTexture(GL_TEXTURE_2D, 0);*/
	}

}; // namespace Font